package com.balloon.gateway.security.handler;

import com.balloon.gateway.comm.ResultVO;
import com.balloon.gateway.comm.ResultVOUtils;
import com.balloon.gateway.enums.StatusCodeEnums;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.server.ServerAuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;

/**
 * @author liaofuxing
 * @version 1.0.0
 * @date 2022/3/8 12:32
 * @description 未授权
 */
@Component
public class DefaultAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {
    private static final Logger logger = LoggerFactory.getLogger(DefaultAuthenticationEntryPoint.class);
    @Override
    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException ex) {
        logger.info(StatusCodeEnums.UNAUTHORIZED.getName());
        return Mono.defer(() -> Mono.just(exchange.getResponse())).flatMap(response -> {
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            ResultVO<String> resultVO = ResultVOUtils.unauthorized(StatusCodeEnums.UNAUTHORIZED.getName());
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                String json = objectMapper.writeValueAsString(resultVO);
                DataBuffer buffer = dataBufferFactory.wrap(json.getBytes(
                        Charset.defaultCharset()));
                return response.writeWith(Mono.just(buffer));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return Mono.error(new Exception());
        });
    }
}